﻿// <copyright file="TileImages.cs" company="TenneySoftware">
// Copyright (c) 2009 All Right Reserved
// </copyright>
// <author>Robert Tenney</author>
// <email>rob10e@yahoo.com</email>
// <date>9/19/2009</date>
// <summary>The images associated with each tile.</summary>

// License:

// Product: ASCII_GDI.csproj
// Author: Robert N. Tenney
// Copyright: 9/19/2009

// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation version 2
// of the License.

// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

// This license covers all source code, binaries, and other materials related to this project
// unless specifically stated otherwise.

using System;
using System.Collections.Generic;
using System.Drawing;

using TenneySoftware.Engine;

namespace TenneySoftware.GraphicsManagers {
    /// <summary>
    /// Structure for storing data for a tile's type/state along with the associated
    /// map image and level image.
    /// </summary>
    [Serializable]
    public class TileImages : IComparable<TileImages>, IComparer<TileImages> {
        /// <summary>
        /// Tile identifier.
        /// </summary>
        private string tile;

        /// <summary>
        /// Level image.
        /// </summary>
        private Bitmap levelImage;

        /// <summary>
        /// Map image.
        /// </summary>
        private Bitmap mapImage;

        /// <summary>
        /// Shadowed level image.
        /// </summary>
        private Bitmap levelImageShadow;

        /// <summary>
        /// Shadowed map image.
        /// </summary>
        private Bitmap mapImageShadow;

        /// <summary>
        /// Highlighted level image.
        /// </summary>
        private Bitmap levelImageHiLite;

        /// <summary>
        /// Highlighted map image.
        /// </summary>
        private Bitmap mapImageHiLite;

        /// <summary>
        /// Flag that indicates if this tile is static or dynamic.
        /// </summary>
        private bool isStatic = true;

        /// <summary>
        /// Gets or sets a value indicating whether this tile is static or dynamic.
        /// </summary>
        /// <value>
        /// Flag indicating whether this tile is static or dynamic.</value>
        public bool IsStatic {
            get {
                return this.isStatic;
            }

            set {
                this.isStatic = value;
            }
        }

        /// <summary>
        /// Gets or sets the tile's DrawableTile enumeration.
        /// </summary>
        /// <value>
        /// The tile's DrawableTile enumeration.
        /// </value>
        public string Tile {
            get {
                return this.tile;
            }

            set {
                this.tile = value;
            }
        }

        /// <summary>
        /// Gets or sets the level image for this tile.
        /// </summary>
        /// <value>
        /// The level image for this tile.
        /// </value>
        public Bitmap LevelImage {
            get {
                return this.levelImage;
            }

            set {
                this.levelImage = value;
            }
        }

        /// <summary>
        /// Gets or sets the map image for this tile.
        /// </summary>
        /// <value>
        /// The map image for this tile.
        /// </value>
        public Bitmap MapImage {
            get {
                return this.mapImage;
            }

            set {
                this.mapImage = value;
            }
        }

        /// <summary>
        /// Gets or sets the shadow level image for this tile.
        /// </summary>
        /// <value>
        /// The shadow level image for this tile.
        /// </value>
        public Bitmap LevelImageShadow {
            get {
                return this.levelImageShadow;
            }

            set {
                this.levelImageShadow = value;
            }
        }

        /// <summary>
        /// Gets or sets the shadow map image for this tile.
        /// </summary>
        /// <value>
        /// The shadow level image for this tile.
        /// </value>
        public Bitmap MapImageShadow {
            get {
                return this.mapImageShadow;
            }

            set {
                this.mapImageShadow = value;
            }
        }

        /// <summary>
        /// Gets or sets the highlight level image for this tile.
        /// </summary>
        /// <value>
        /// The highlight level image for this tile.
        /// </value>
        public Bitmap LevelImageHighlight {
            get {
                return this.levelImageHiLite;
            }

            set {
                this.levelImageHiLite = value;
            }
        }

        /// <summary>
        /// Gets or sets the highlight map image for this tile.
        /// </summary>
        /// <value>
        /// The highlight map image for this tile.
        /// </value>
        public Bitmap MapImageHighlight {
            get {
                return this.mapImageHiLite;
            }

            set {
                this.mapImageHiLite = value;
            }
        }

        /// <summary>
        /// Compares two objects to determine if they're the same.
        /// Compared by the tile's ToString() representation.
        /// </summary>
        /// <param name="first">First object to compare.</param>
        /// <param name="second">Second object to compare.</param>
        /// <returns>True if the two objects are the same.</returns>
        public static bool operator ==(TileImages first, TileImages second) {
            return first.Equals(second);
        }

        /// <summary>
        /// Compares two objects to determine if they're not the same.
        /// Compared by the tile's ToString() representation.
        /// </summary>
        /// <param name="first">First object to compare.</param>
        /// <param name="second">Second object to compare.</param>
        /// <returns>True if the two objects are not the same.</returns>
        public static bool operator !=(TileImages first, TileImages second) {
            return !(first == second);
        }

        /// <summary>
        /// Compares two objects to determine if the first one is less than the second.
        /// Compared by the tile's ToString() representation.
        /// </summary>
        /// <param name="first">First object to compare.</param>
        /// <param name="second">Second object to compare.</param>
        /// <returns>True if the first object is less than the second one.</returns>
        public static bool operator <(TileImages first, TileImages second) {
            return first.CompareTo(second) < 0;
        }

        /// <summary>
        /// Compares two objects to determine if the first one is greater than the second.
        /// Compared by the tile's ToString() representation.
        /// </summary>
        /// <param name="first">First object to compare.</param>
        /// <param name="second">Second object to compare.</param>
        /// <returns>True if the first object is greater than the second one.</returns>
        public static bool operator >(TileImages first, TileImages second) {
            return first.CompareTo(second) > 0;
        }

        /// <summary>
        /// Compares another object to this instance.
        /// </summary>
        /// <param name="other">The other object to compare to.</param>
        /// <returns>True if the two objects are the same.</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1800:DoNotCastUnnecessarily", Justification = "other is check before casting")]
        public int CompareTo(object other) {
            if (!(other is TileImages)) {
                throw new ArgumentException(
                    "A TileImages object is required for comparison.");
            }

            return this.CompareTo((TileImages)other);
        }

        /// <summary>
        /// Converts this object to a string.
        /// </summary>
        /// <returns>The string representation of this object.</returns>
        public override string ToString() {
            return this.Tile.ToString();
        }

        /// <summary>
        /// Compares another TileImages object to this instance.
        /// Compared by the tile's ToString() representation.
        /// </summary>
        /// <param name="other">The other TileImages object to compare to.</param>
        /// <returns>True if the two objects are the same.</returns>
        public int CompareTo(TileImages other) {
            return string.Compare(this.ToString(), other.ToString(), StringComparison.OrdinalIgnoreCase);
        }

        /// <summary>
        /// Compare two TileImages objects to determine if they are the same.
        /// Compared by the tile's ToString() representation.
        /// </summary>
        /// <param name="x">First object to compare.</param>
        /// <param name="y">Second object to compare.</param>
        /// <returns>True if the objects are the same.</returns>
        public int Compare(TileImages x, TileImages y) {
            return x.CompareTo(y);
        }

        /// <summary>
        /// Compares another object to this instance to determine if they're the same. Overridden.
        /// Compared by the tile's ToString() representation.
        /// </summary>
        /// <param name="obj">Object to compare to.</param>
        /// <returns>True if the objects are the same.</returns>
        public override bool Equals(object obj) {
            if (!(obj is TileImages)) {
                return false;
            }

            return this.CompareTo(obj) == 0;
        }

        /// <summary>
        /// Generates a unique hash code for this instance.
        /// </summary>
        /// <returns>A unique hash code.</returns>
        public override int GetHashCode() {
            char[] c = this.ToString().ToCharArray();
            return (int) c[0];
        }
    }
}
